#include "Socket.hpp"
#include "Epoll.hpp"
#include <functional>
#include <memory>

class Acceptor
{
public:
    Acceptor(uint16_t port, \
            const std::function<void(int)>& readCallback, \
            const std::function<void(int)>& writeCallback, \
            const std::function<void(int)>& errorCallback, \
            std::shared_ptr<Epoll> epoller, \
            const std::function<void(const std::string&)>& onMessage)
        :_port(port), _listenFd(-1),\
         _readCallback(readCallback), _writeCallback(writeCallback), _errorCallback(errorCallback),\
         _epoller(epoller)
    {}

    bool Init()
    {
        _listenSock.Sock();
        _listenSock.Bind(_port);
        _listenSock.Listen();
    }

    bool Start()
    {
        // 绑定cb
        _readCallback = std::bind(&Acceptor::OnRead, this, std::placeholders::_1);
        // 将Acceptor注册到epoll
        _epoller->Add(Connection(_listenFd, nullptr, nullptr, nullptr, _epoller.get()), EPOLLIN);
    }

    void SetOnMessage(const std::function<void(const std::string&)>& onMessage)
    {
        _onMessage = onMessage;
    }

private:
    void OnRead(int)
    {
        std::string ip;
        uint16_t port = 0;
        int connFd = _listenSock.Accept(&ip, &port);
        if (connFd >= 0)
        {
            // 封装Connection
            Connection conn(connFd, nullptr, nullptr, _onMessage, _epoller.get());
            // 注册到epoll
            _epoller->Add(conn, EPOLLIN | EPOLLOUT);
        }
    }

private:
    Socket _listenSock;
    uint16_t _port;
    int _listenFd;
    std::function<void(int)> _readCallback;
    std::function<void(int)> _writeCallback;
    std::function<void(int)> _errorCallback;
    std::shared_ptr<Epoll> _epoller;
    std::function<void(const std::string&)> _onMessage;
};